package mymyoux.events
{
	import flash.events.EventDispatcher;
	
	import mymyoux.core.IObject;
	/**
	 * MEventDispatcher est un EventDispatcher capable de supprimer tous ses écouteurs. Diminue le risque de Memory-leak
	 * @author Mymyoux
	 * @version 1.0
	 */
	public class MEventDispatcher extends EventDispatcher implements IObject
	{
		/**
		 * Contient la liste des écouteurs
		 */
		private var list:Array;
		/**
		 * Crée un nouvel objet MEventDispatcher
		 */
		public function MEventDispatcher(){
			list=new Array();
		}
		/**
		 * Enregistre un écouteur(listener) avec le MEventDispatcher pour que cet écouteur reçoive les notifications d'un évènement.
		 * @param type	Le type de l'évènement.
		 * @param listener	L'écouteur qui reçoit l'évènement. IL doit accepter un évènement comme seul paramètre et ne rien renvoyer.
		 * @param useCapture	Determines whether the listener works in the capture phase or the target and bubbling phases. If useCapture  is set to true  , the listener processes the event only during the capture phase and not in the target or bubbling phase. If useCapture  is false  , the listener processes the event only during the target or bubbling phase. To listen for the event in all three phases, call addEventListener  twice, once with useCapture  set to true  , then again with useCapture  set to false  . 
		 * @param priority	The priority level of the event listener. The priority is designated by a signed 32-bit integer. The higher the number, the higher the priority. All listeners with priority n  are processed before listeners of priority n  -1. If two or more listeners share the same priority, they are processed in the order in which they were added. The default priority is 0. 
		 * @param	useWeakReference	Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.	Class-level member functions are not subject to garbage collection, so you can set useWeakReference to true for class-level member functions without subjecting them to garbage collection. If you set useWeakReference to true for a listener that is a nested inner function, the function will be garbage-collected and no longer persistent. If you create references to the inner function (save it in another variable) then it is not garbage-collected and stays persistent. 
		 * @return void
		 */
		public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void{
			super.addEventListener(type,listener,useCapture,priority,useWeakReference);
			list.push(new MListener(type,listener,useCapture));
		}
		/**
		 * Supprime un écouteur(listener) du MEventDispatcher pour que cet écouteur ne reçoive plus les notifications d'un évènement. 
		 * Si l'écouteur n'était pas enregistré, la fonction n'a aucun effet.
		 * @param type	Le type de l'évènement.
		 * @param listener	L'écouteur qui reçevait l'évènement.
		 * @param useCapture	Determines whether the listener works in the capture phase or the target and bubbling phases. If useCapture  is set to true  , the listener processes the event only during the capture phase and not in the target or bubbling phase. If useCapture  is false  , the listener processes the event only during the target or bubbling phase. To listen for the event in all three phases, call addEventListener  twice, once with useCapture  set to true  , then again with useCapture  set to false  . 
		 * @return void
		 */
		public override function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void{
			super.removeEventListener(type,listener,useCapture);
			for(var i:String in list){
				if(list[i].type==type && list[i].listener==listener && list[i].useCapture==useCapture){
					list.splice(i,1);
				}
			}
		}
		/**
		 * Supprime tous les écouteurs liés au MEventDispatcher pour qu'ils ne reçoivent plus d'évènements.
		 */
		public function removeAllEventListener():void{
			var a:Array=new Array();
			for(var i:String in list){
				a.push(list[i]);
			}
			for(i in a){
				removeEventListener(a[i].type,a[i].listener,a[i].useCapture);
			}
		}
		/**
		 * Indique le nombre d'écouteurs liés au MDispatcherEvent
		 */
		public function get length():uint{
			return list.length;
		}
		/**
		 * @inheritDoc 
		 */
		public function destroy():void{
			removeAllEventListener();
		}
		 /**
		 * @inheritDoc 
		 */
		public function equals(objet:IObject):Boolean{
			return objet===this;
		}
	}
}
internal class MListener{
	private var _t:String,_l:Function,_u:Boolean;
	public function MListener(type:String,listener:Function,useCapture:Boolean){
		_t=type;
		_l=listener;
		_u=useCapture;
	}
	public function get type():String{
		return _t;
	}
	public function get listener():Function{
		return _l;
	}
	public function get useCapture():Boolean{
		return _u;
	}
	public function toString():String{
		return "[MListener type=\""+_t+"\" useCapture=\""+_u+"\"]";
	}
}